package com.alinesno.cloud.common.web.base.exceptions;

import java.io.IOException;
import java.util.List;

import javax.lang.exception.RpcServiceRuntimeException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import com.alinesno.cloud.common.core.health.HealthExceptions;
import com.alinesno.cloud.common.facade.response.ResponseBean;
import com.alinesno.cloud.common.facade.response.ResponseGenerator;
import com.alinesno.cloud.common.web.base.form.FormRepeatException;

/**
 * 统一异常处理包
 * 
 * @author WeiXiaoJin
 * @since 2019年9月18日 上午8:23:48
 */
public class WebExceptionUtils {

	private static final Logger log = LoggerFactory.getLogger(WebExceptionUtils.class);
	private static final String ERROR_BUSINESS = "/errorBusiness" ;  

	/**
	 * 统一前端异常处理实现
	 * 
	 * @return
	 */
	public static ResponseBean handleException(Exception e, BindingResult result , HttpServletRequest request) {

		String message = e.getMessage();
		String eclass = e.getClass().getName();

		log.error("前端调用异常 , eclass:{} , message:{} " , eclass , message , e);

		String errorMsg = "应用异常.";

		if (e instanceof FormRepeatException) {

			errorMsg = e.getMessage();

		} else if (message != null && message.startsWith(RpcServiceRuntimeException.class.getName())) {

			errorMsg = message.substring(message.indexOf(":") + 1, message.indexOf("\n") - 1);

		} else if (eclass != null && eclass.startsWith("org.apache.dubbo.rpc.RpcException")) {

			errorMsg = "远程服务连接不可用,请确认服务是否正常.";

		} else if (eclass != null && eclass.startsWith("feign.FeignException")) {

			errorMsg = "远程服务连接异常,请联系服务管理员处理:" + message;

		}else if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException) {

			errorMsg = e.getMessage();
			
		} else if(eclass != null && eclass.startsWith("javax.lang.exception.RpcServiceRuntimeException")){
			
			errorMsg = e.getMessage();
			
		} else if (e instanceof BindException) {

			if(result != null) {
				String errorMessage = "请求参数异常:<br/>";
				if (result.hasErrors()) {
					List<ObjectError> allErrors = result.getAllErrors();
					for (ObjectError error : allErrors) {
						log.debug(error.getDefaultMessage());
						errorMessage = error.getDefaultMessage(); // +"<br/>" ;
						break;
					}
				}
				
				errorMsg = errorMessage ;
			}
			
		} else {
			errorMsg = "系统异常，请重试或者联系管理员！" ; // StringUtils.isEmpty(e.getMessage()) ? "系统异常，请重试或者联系管理员！" : e.getMessage();
		}

		if("null".equals(errorMsg)) {
			errorMsg = "系统异常，请重试或者联系管理员！" ; 
		}
		
		// 发送消息异常信息
		HealthExceptions.sendException(e);
		
		return ResponseGenerator.genFailMessage(errorMsg);
	}

	/**
	 * 权限异常处理
	 * @param e
	 * @return
	 */
	public static ResponseBean handleAuthException(Exception e , HttpServletRequest request) {
		String message = e.getMessage();
		String eclass = e.getClass().getName();

		log.error("前端调用异常 , eclass:{} , message:{} " , eclass , message , e);
		
		return ResponseGenerator.genFailMessage("用户没有操作权限.");
	}

	/* * 
	 * 判断是否为ajax请求 , 默认为ajax请求
	 */
	public static boolean isAjax(HttpServletRequest request){
		if(request == null) {
			return true ; 
		}
		
		String rw = request.getHeader("X-Requested-With") ; 
		if(rw != null && "XMLHttpRequest".equals(rw)) {
			return true ; 
		}
	
		return false ; 
	}
	
	/**
	 * 异常页面处理
	 * @param rb
	 * @param request
	 * @param response
	 * @return
	 */
	public static ResponseBean errorRedirect(ResponseBean rb , HttpServletRequest request , HttpServletResponse response) {
		if(!WebExceptionUtils.isAjax(request)) {
	        try {
				WebUtils.redirectToSavedRequest(request, response , ERROR_BUSINESS);
			} catch (IOException e1) {
				log.error("页面异常:"+e1);
			} 
			return null ; 
		}	
		return rb ; 
	}
	

}
